package itypes

import (
	"server/game/model"
	"server/share/config"

	"github.com/hwcer/logger"
	"github.com/hwcer/updater"
	"github.com/hwcer/updater/dataset"
	"github.com/hwcer/updater/operator"
)

const (
	RoleModelPlug = "_model_role_plug"
)

var Role = &roleIType{IType: NewIType(config.ITypeRole)}

func init() {
	//Role.Upgrade = roleUpgradeDefault{}
	it := []updater.IType{Role}
	//ROLE
	if err := updater.Register(updater.ParserTypeDocument, updater.RAMTypeAlways, &model.Role{}, it...); err != nil {
		logger.Panic(err)
	}
}

type roleIType struct {
	*IType
}

func (this *roleIType) All(u *updater.Updater) *model.Role {
	return u.Handle(config.ITypeRole).(*updater.Document).Any().(*model.Role)
}
func (this *roleIType) ObjectId(u *updater.Updater, iid int32) string {
	return u.Uid()
}

// Listener 监听升级状态

func (this *roleIType) Listener(u *updater.Updater, op *operator.Operator) {
	if op.Type == operator.TypesAdd && (op.Key == "exp" || op.Key == "Exp") {
		if exp := this.verify(u, op.Value); exp > 0 {
			op.Value = exp
			_ = u.Events.LoadOrCreate(RoleModelPlug, this.NewMiddleware)
		} else {
			op.Type = operator.TypesDrop //最大等级不给经验
		}
	}
}

// G2SOAuth 获得经验时进行检查
func (*roleIType) verify(u *updater.Updater, exp int64) (newExp int64) {
	//lv := u.Val(define.ItemTypeLV)
	//if _, ok := config.Data.Level[int32(lv+1)]; !ok {
	//	return 0
	//}
	return exp
}

func (this *roleIType) NewMiddleware() updater.Middleware {
	return &RoleMiddleware{}
}

type RoleMiddleware struct {
}

func (this RoleMiddleware) Emit(u *updater.Updater, t updater.EventType) bool {
	if t == updater.EventTypeSubmit {
		return this.upgrade(u)
	}
	return true
}

func (this RoleMiddleware) Release(u *updater.Updater) bool {
	return false
}

func (this RoleMiddleware) upgrade(u *updater.Updater) bool {
	h := u.Document(config.ITypeRole)
	r := h.Any().(*model.Role)
	exp := dataset.ParseInt64(h.Get("exp"))
	if newLv, newExp := this.newLv(u, r.Lv, exp); newLv > r.Lv {
		//升级奖励
		//for i := r.Lv + 1; i <= newLv; i++ {
		//	if c := config.Data.PlayerExp[i]; c != nil && c.LevelBonus > 0 {
		//		u.Add(c.LevelBonus, 1)
		//	}
		//}
		h.Add("lv", newLv-r.Lv)
		h.Set("exp", newExp)
	}
	return false
}

// Submit 判断升级，返回新的等级
func (RoleMiddleware) newLv(_ *updater.Updater, lv int32, exp int64) (newLv int32, newExp int64) {
	newLv = lv
	newExp = exp

	for i := lv + 1; ; i++ {
		c := config.Data.PlayerExp[i]
		if c != nil && c.Exp > 0 && newExp >= c.Exp {
			newLv = i
			newExp -= c.Exp
		} else {
			break
		}
	}
	return
}
